import logging
from django.contrib.auth import login, authenticate,logout
from django.db import DatabaseError
from django.views import View
from django import http
from django_redis import get_redis_connection
from django.utils.decorators import method_decorator
from utils.param_checking import image_file
from django.conf import settings

import json
import re

from users.models import User
from utils.response_code import RET
from utils.decorators import login_required
from libs.qiniuyun.qiniu_storage import storage


logger = logging.getLogger("django")


class RegisterView(View):
    """
    用户注册
    """
    def post(self,request):

        # 接收参数
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get("mobile")
        phonecode = dict_data.get("phonecode")
        password = dict_data.get("password")

        # 校验参数
        if not all([mobile,phonecode,password]):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数不全"})

        # 判断手机号是否合法
        if not re.match(r"^1[3-9]\d{9}$",mobile):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"请输入正确的手机号码"})

        # 判断密码
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"请输入8-20位密码"})

        # 校验用户输入的验证码是否正确
        redis_coon = get_redis_connection("verify_code")
        real_sms_code = redis_coon.get("sms_%s" % mobile)
        if not real_sms_code:
            return http.JsonResponse({"errno":RET.NODATA,"errmsg":"验证码已失效"})
        if real_sms_code.decode() != phonecode:
            return http.JsonResponse({"errno":RET.DATAERR,"errmsg":"短信验证码输入错误"})

        # 保存用户注册数据
        try:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        except DatabaseError:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "注册失败"})

        # 状态保持
        login(request, user)

        return http.JsonResponse({"errno":RET.OK,"errmsg":"注册成功"})


class LoginView(View):
    """
    用户登陆
    """

    def get(self,request):
        """
        判断用户是否登陆
        """
        # 获取到user
        user = request.user
        # 认证
        if not user.is_authenticated:
            return http.JsonResponse({"errno": RET.SESSIONERR, "errmsg": "用户未登录"})

        # 对象.属性--点出id和用户名
        data = {
            "user_id":user.id,
            "name":user.username
        }
        return http.JsonResponse({"errno": RET.OK, "errmsg": "已登录", "data": data})


    def post(self,request):

        # 接收参数
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get("mobile")
        password = dict_data.get("password")

        # 校验参数
        # 校验参数是否齐全
        if not all([mobile,password]):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数不全"})

        # 判断密码是否符合
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({"errno": RET.PARAMERR, "errmsg": "请输入正确的手机号码"})

        # 认证用户
        user = authenticate(request,username=mobile,password=password)
        if not user:
            return http.JsonResponse({"errno": RET.LOGINERR, "errmsg": "请输入正确的手机号码"})

        # 实现状态保持
        login(request,user)

        # 返回响应
        return http.JsonResponse({"errno":RET.OK,"errmsg":"登陆成功"})


    def delete(self,request):
        """退出登陆"""

        logout(request)
        return http.JsonResponse({"errno":RET.OK,"errmsg":"已登出"})


class UserInfo(View):
    """
    用户个人中心
    """
    # 添加装饰器:判断用户是否登陆
    @method_decorator(login_required)
    def get(self,request):

        # 获取user
        user = request.user

        return http.JsonResponse({"errno":RET.OK,"errmsg":"OK","data":user.to_basic_dict()})


class PhotoView(View):
    """上传头像"""

    @method_decorator(login_required)
    def post(self,request):
        # 接收参数
        avatar = request.FILES.get("avatar")

        if not avatar:
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数错误"})

        if not image_file(avatar):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数错误"})

        # 读取文件二进制
        file_data = avatar.read()

        try:
            key = storage(file_data)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({"errno": RET.THIRDERR, "errmsg": "上传图片失败"})
        try:
            request.user.avatar = key
            request.user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": RET.SERVERERR, "errmsg": "图片保存失败"})

        data = {
            "avatar_url": settings.QINIU_URL + key
        }
        return http.JsonResponse({"errno": RET.OK, "errmsg": "OK", "data": data})


class ModifyNameView(View):
    """
    修改用户名
    """
    @method_decorator(login_required)
    def put(self,request):
        dict_data = json.loads(request.body.decode())
        username = dict_data.get("name")

        # 获取user对象
        user = request.user
        try:
            user.username = username
            user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": RET.SERVERERR, "errmsg": "数据保存失败"})

        return http.JsonResponse({"errno": RET.OK, "errmsg": "修改成功"})


class UserAuth(View):
    """
    用户名实名认证
    """

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(UserAuth,self).dispatch(request,*args,**kwargs)

    def get(self,request):
        # 显示认证信息
        data = request.user.to_auth_dict()

        return http.JsonResponse({"errno": RET.OK, "errmsg": '认证信息查询成功',  "data": data})

    def post(self,request):

        # 保存用户认证信息
        dict_data = json.loads(request.body.decode())
        real_name = dict_data.get("real_name")
        id_card = dict_data.get("id_card")

        # 校验参数
        if not all([real_name,id_card]):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数错误"})

        # 获取user对象
        user = request.user

        try:
            user.real_name = real_name
            user.id_card = id_card
            user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": RET.SERVERERR, "errmsg": "数据保存失败"})
        else:
            return http.JsonResponse({"errno": RET.OK, "errmsg": '认证信息保存成功'})
